/*
 * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @Date: 2025-02-10 09:46:01
 * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @LastEditTime: 2025-02-10 14:11:18
 * @FilePath: /2024-4-20-pipe/named_pipe/named_pipe.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <cerrno>
#include <cstdio>
#include <string>
#include<unistd.h>
#include<fcntl.h>

using namespace std;

const string com_path = "./myfifo"; // 定义一个：全局路径
#define Defaultfd -1
#define Creator 1
#define User 2
#define Read O_RDONLY
#define Write O_WRONLY
#define BaseSize 4096

// 创建一个命名管道的类
class named_pipe
{
private:
    bool OpenNamedPipe(int mode)
    {
        _fd=open(_fifo_path.c_str(),mode);
        if(_fd<0)
            return false;
        return true;
    }
public:
    named_pipe(const string &path, int who) // 构造函数参数：1你要创建的路径?  2是谁创建的？
        : _fifo_path(path), _id(who), _fd(Defaultfd)
    {
        if(_id==Creator)// 只有id等于creator，我才给你创建命名管道。
        {
            int ret=mkfifo(_fifo_path.c_str(),0666);
            if(ret!=0)
            {
                perror("mkfifo fail");
            }
            cout<<"Creator create named_pipe"<<endl;
        }
    }

    bool OpenForRead()
    {
        return OpenNamedPipe(Read);
    }
    bool OpenForWrite()
    {
        return OpenNamedPipe(Write);
    }

    int ReadNamedPipe(string* out)
    {
        char buffer[BaseSize];
        int n=read(_fd,buffer,sizeof(buffer));
        if(n>0)
        {
            *out=string(buffer,n);
        }
        return n;
    }

    int WriteNamedPipe(string &in)
    {
        return write(_fd,in.c_str(),in.size());
    }

    ~named_pipe()
    {
        if(_id==Creator)
        {
            int ret=unlink(_fifo_path.c_str());
            if(ret!=0)
            {
                perror("unlink fail");
            }
            cout<<"Creator free named_pipe"<<endl;
        }
        if(_fd!=Defaultfd) close(_fd);
    }

private:
    const string _fifo_path;
    int _id;
    int _fd;
};
